package com.colin.util.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

public class DateUtil {
    public final static DateTimeFormatter yyyyMMddFormat = DateTimeFormatter.ofPattern("yyyyMMdd");

    public final static DateTimeFormatter yyMMddFormat = DateTimeFormatter.ofPattern("yyMMdd");

    public final static DateTimeFormatter yyyy_MM_ddFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    public final static DateTimeFormatter yyyy_MM_ddHHmmssFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    public final static DateTimeFormatter yyyyMMddHHmmssFormat = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

    public final static DateTimeFormatter yyyy_MM_ddHHmmFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");

    public static LocalDateTime date2LocalDateTime(Date date){
        return date.toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalDateTime();
    }

    public static Date localDateTime2Date(LocalDateTime localDateTime){
        return Date.from( localDateTime.atZone( ZoneId.systemDefault()).toInstant());
    }

    /**
     * 得到当前日期
     * @return String 当前日期 yyyyMMdd格式
     */
    public static String getCurDateYYYYMMDD() {
        LocalDateTime localDateTime = LocalDateTime.now();
        return yyyyMMddFormat.format(localDateTime);
    }

    /**
     * 格式化时间为yyyyMMdd
     */
    public static String toDateStryyyyMMdd(Date date) {
        LocalDateTime localDateTime = date2LocalDateTime(date);
        return yyyyMMddFormat.format(localDateTime);
    }

    /**
     * 返回日期格式(yyyyMMddHHmmss)
     */
    public static String toDateTimeStr2(Date date) {
        if (date == null) {
            return "";
        }
        LocalDateTime localDateTime = date2LocalDateTime(date);
        return yyyyMMddHHmmssFormat.format(localDateTime);
    }

    /**
     * 获取某个月后的日期格式（yyyyMMdd）
     *
     * @return
     */
    public static String getAfterMonthyyyyMMdd(int monthNum) {
        LocalDateTime localDateTime = LocalDateTime.now().plusMonths(monthNum);
        return yyyyMMddFormat.format(localDateTime);
    }

    /**
     * 得到当前日期
     * @return String 当前日期 yyMMdd格式
     */
    public static String getCurDateYYMMDD() {
        LocalDateTime localDateTime = LocalDateTime.now();
        return yyMMddFormat.format(localDateTime);
    }

    /**
     * 得到当前日期
     *
     * @return String 当前日期 yyyy-MM-dd HHmmSS格式
     */
    public static String getCurDateTime() {
        LocalDateTime localDateTime = LocalDateTime.now();
        return yyyy_MM_ddHHmmssFormat.format(localDateTime);
    }

    /**
     * 返回日期格式(yyyy-MM-dd)
     */
    public static String toDateStr(Date date) {
        if (date == null) {
            return "";
        }
        LocalDateTime localDateTime = date2LocalDateTime(date);
        return yyyy_MM_ddFormat.format(localDateTime);
    }

    /**
     * 将Date类型的日期格式 转换为 符合要求的 String日期格式
     */
    public static String toDateStr(Date date, String format) {
        if (date == null) {
            return "";
        } else {
            LocalDateTime localDateTime = date2LocalDateTime(date);
            DateTimeFormatter df = DateTimeFormatter.ofPattern(format);
            return df.format(localDateTime);
        }
    }

    /**
     * 返回日期格式(yyyy-MM-dd HH:mm:ss)
     */
    public static String toDateTimeStr(Date date) {
        if (date == null) {
            return "";
        }
        LocalDateTime localDateTime = date2LocalDateTime(date);
        return yyyy_MM_ddHHmmssFormat.format(localDateTime);
    }

    /**
     * 获取某个月后的日期格式（yyyy-MM-dd）
     */
    public static String getAfterMonthyyyy_MM_dd(int monthNum) {
        LocalDateTime localDateTime = LocalDateTime.now().plusMonths(monthNum);
        return yyyy_MM_ddFormat.format(localDateTime);
    }

    /**
     * 获取当前系统时间距离传入时间的毫秒数
     *
     * @param strTime
     *            格式[ DD:00:00]
     */
    public static long getSleepTime(String strTime) throws ParseException {
        long p = 1;
        long l_date = System.currentTimeMillis();
        LocalDateTime date_now = LocalDateTime.now();
        String strDate = yyyy_MM_ddFormat.format(date_now) + strTime;
        LocalDateTime dateTime = LocalDateTime.parse(strDate, yyyy_MM_ddHHmmssFormat);
        if (date_now.isBefore(dateTime))
            p = localDateTime2Date(dateTime).getTime() - l_date;
        else {
            dateTime = dateTime.plusDays(1L);
            p = localDateTime2Date(dateTime).getTime() - l_date;
        }
        return p;
    }

    /**
     * 得到当前日期
     * @return String 当前日期 yyyyMMddHHmmSS格式
     */
    public static String getCurTime() {
        LocalDateTime localDateTime = LocalDateTime.now();
        return yyyyMMddHHmmssFormat.format(localDateTime);
    }

    /**
     * 计算指定日期时间之间的时间差
     *
     * @param beginStr 开始日期字符串 yyyy-MM-dd HH:mm:ss
     * @param endStr 结束日期字符串 yyyy-MM-dd HH:mm:ss
     * @param f 时间差的形式0-秒,1-分种,2-小时,3--天 日期时间字符串格式:yyyyMMddHHmmss
     * */
    public static int getInterval(String beginStr, String endStr, int f) throws Exception{
        int hours = 0;

        LocalDateTime begin = LocalDateTime.parse(beginStr, yyyy_MM_ddHHmmssFormat);
        LocalDateTime end = LocalDateTime.parse(endStr, yyyy_MM_ddHHmmssFormat);

        Date beginDate = localDateTime2Date(begin);
        Date endDate = localDateTime2Date(end);
        // 日期相减得到日期差X(单位:毫秒)
        long millisecond = endDate.getTime() - beginDate.getTime();
        /**
         * Math.abs((int)(millisecond/1000)); 绝对值 1秒 = 1000毫秒
         * millisecond/1000 --> 秒 millisecond/1000*60 - > 分钟
         * millisecond/(1000*60*60) -- > 小时 millisecond/(1000*60*60*24) -->
         * 天
         * */
        switch (f) {
            // second
            case 0:
                return (int) (millisecond / 1000);
            // minute
            case 1:
                return (int) (millisecond / (1000 * 60));
            // hour
            case 2: 
                return (int) (millisecond / (1000 * 60 * 60));
            // day
            case 3: 
                return (int) (millisecond / (1000 * 60 * 60 * 24));
            default:
                return hours;
        }
    }

    /**
     * 返回日期格式(yyyy-MM-dd HH:mm)
     */
    public static String toDateTime_ymd_hm(Date date) {
        if (date == null) {
            return "";
        }
        LocalDateTime localDateTime = date2LocalDateTime(date);
        return yyyy_MM_ddHHmmFormat.format(localDateTime);
    }

    /**
     * 获取截止时间
     * @param date 实际截止时间
     * @param time 店铺提前时间(分)
     */
    public static Date changeDate( Date date , int time ){
        Calendar dar = Calendar.getInstance();
        dar.setTime(date);
        dar.add(Calendar.MINUTE, -time);
        return dar.getTime();
    }

    /**
     * 获取两个时间差，返回毫秒值
     * @param date1
     * @param date2
     * @return
     */
    public static long remindTime(Date date1, Date date2){
        return date1.getTime() - date2.getTime();
    }

    /**
     * 获得当前时间到未来目标时间的秒差
     */
    public static int getSecondsInterval(Date target){
        int hours = 0;
        try {
            Date beginDate = new Date();
            long millisecond = target.getTime() - beginDate.getTime(); // 日期相减得到日期差X(单位:毫秒)
            return (int) (millisecond / 1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return hours;
    }

    public static Date getDateTime(String date) {
        if (date == null || date.trim().equals("")) {
            return null;
        } else {
            if(date.contains(".")){
                date = date.substring(0, date.indexOf("."));
            }
            LocalDateTime begin = LocalDateTime.parse(date, yyyy_MM_ddHHmmssFormat);
            return localDateTime2Date(begin);
        }
    }

    public static Integer getEndTime(){
        Date date=new Date();
        Calendar midnight=Calendar.getInstance();
        midnight.setTime(date);
        midnight.add(Calendar.DAY_OF_MONTH,1);
        midnight.set(Calendar.HOUR_OF_DAY,0);
        midnight.set(Calendar.MINUTE,0);
        midnight.set(Calendar.SECOND,0);
        midnight.set(Calendar.MILLISECOND,0);
        Integer seconds=(int)((midnight.getTime().getTime()-date.getTime())/1000);
        return seconds;
    }

    /**
     * 获取当前时间前几天或后几天的日期
     */
    public static Date getAddDays(int days) {
        Calendar calendar = new GregorianCalendar();
        calendar.add(Calendar.DAY_OF_YEAR, days);
        return calendar.getTime();
    }

    /**
     * 得到起始日期和结束日期之间的天数
     * @param beginStr
     *            起始日期 yyyy-MM-dd HH:mm:ss格式
     * @param endStr
     *            结束日期 yyyy-MM-dd HH:mm:ss格式
     * @return 天数
     */
    public static int getDaysInterval(String beginStr, String endStr) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        try {
            int daysInterval = 0;
            Date beginDate = format.parse(beginStr);
            Date endDate = format.parse(endStr);
            long millisecond = endDate.getTime() - beginDate.getTime(); // 日期相减得到日期差X(单位:毫秒)
            int s = (int) (millisecond / (1000 * 60 * 60 * 24));//商
            int y = (int) (millisecond % (1000 * 60 * 60 * 24));//余数
            if(y != 0 ){
                daysInterval = s +1;
            }else{
                daysInterval = s;
            }
            return daysInterval;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return 0;
    }
    
    public static String getCurYYYYMM(){
        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMM");
        return simpleDateFormat.format(date);
    }

    /**
     * 获取当前月天数
     */
    public static int getDaysOfCurMonth(){
        Calendar aCalendar = Calendar.getInstance();
        return aCalendar.getActualMaximum(Calendar.DATE);
    }

    /**
     * 获取当前位于当月的第几天
     */
    public static int getCurDayOfCurMonth(){
        Calendar calendar = Calendar.getInstance();
        return calendar.get(Calendar.DAY_OF_MONTH);
    }

    /**
     * 获取当前位于当周的第几天
     * 按照中国的习惯调整，1为周一，7为周日
     */
    public static int getCurDayOfCurWeek(){
        Calendar calendar = Calendar.getInstance();
        return (calendar.get(Calendar.DAY_OF_WEEK)-1)==0?7:(calendar.get(Calendar.DAY_OF_WEEK)-1);
    }

    /**
     * 获取当前时间戳
     * @return 时间戳
     */
    public static long getNowTimeStamp(){
        return System.currentTimeMillis();
    }

    /**
     * 从指定格式的时间字符串获取时间戳
     * @param dateStr 时间字符串
     * @param format 时间格式
     * @return 时间戳
     */
    public static long getTimeStampFromString(String dateStr, String format){
        //获取时间
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        try {
            Date parse = simpleDateFormat.parse(dateStr);
            return parse.getTime();
        } catch (ParseException e) {
            LogUtil.error("getTimeStampFromString_error:", e);
        }
        return 0L;
    }

    /**
     * 时间戳转为时间对象
     * @param timestamp 时间戳
     * @return 时间对象java.util.Date
     */
    public static Date timeStamp2Date(long timestamp){
        return new Date(timestamp);
    }

    public static void main(String[] args) {
        String format = "yyyy-MM-dd HH:mm:ss";
        String dateStr = "2021-02-24 14:21:25";
        long stamp = getTimeStampFromString(dateStr, format);
        System.out.println(stamp);
        Date date = timeStamp2Date(stamp);
        System.out.println(toDateStr(date, format));
    }

}
